<?php
namespace backend\models;

use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use yii\db\Query;
use common\helps\tree;
use yii\db\Exception;


/**
 * User model
 *
 * @property integer $id
 * @property string $username
 * @property string $password_hash
 * @property string $password_reset_token
 * @property string $email
 * @property string $auth_key
 * @property integer $status
 * @property integer $created_at
 * @property integer $updated_at
 * @property string $password write-only password
 */
class Admin extends ActiveRecord implements IdentityInterface
{
    const STATUS_DELETED = 0;
    const STATUS_ACTIVE = 10;
    const STATUS = 1;
    public $repassword;
    public $role_id;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%admin}}';
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            TimestampBehavior::className(),
        ];
    }

    public static function findAllData()
    {
        $query = new \yii\db\Query();
        $query->select(['*'])->from('admin');
        $query->where(['deleted_at' => null]);
        $query->where(['status' => self::STATUS]);
        $command = $query->createCommand();
        $result = $command->queryAll();
        //var_dump($query->createCommand()->getRawSql());exit;
        return $result;
    }

    public static function selectData($field = '*')
    {
        $query = new \yii\db\Query();
        $query->select([$field])->from('admin');
        $query->where(['deleted_at' => null]);
        $query->where(['status' => self::STATUS]);
        $command = $query->createCommand();
        $result = $command->queryAll();
        //var_dump($query->createCommand()->getRawSql());exit;
        return $result;
    }

    public static function findOneData($token)
    {
        $query = new \yii\db\Query();
        $query->select(['*'])->from('admin');
        $query->where(['deleted_at' => null]);
        $query->andWhere(['status' => self::STATUS]);
        $query->andWhere(['token' => $token]);
        $command = $query->createCommand();
        $result = $command->queryOne();
        //var_dump($query->createCommand()->getRawSql());exit;
        return $result;
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['username', 'password','repassword','true_name','mobile'], 'trim'],
            ['username', 'unique', 'message'=>'用户名已注册','on' => ['create','default']],
            [['username', 'password','repassword','true_name','role_id','id'], 'required','message' =>'{attribute}不能为空'],
            [['username'],'string','max'=>20, 'min'=>3, 'tooLong'=>'{attribute}请输入长度为3-20位字符', 'tooShort'=>'{attribute}请输入长度为3-20位字符'],
//            [['password'],'string','max'=>20, 'min'=>3, 'tooLong'=>'{attribute}请输入长度为3-20位字符', 'tooShort'=>'{attribute}请输入长度为3-20位字符'],
            [['true_name'],'string','max'=>20, 'min'=>2, 'tooLong'=>'{attribute}请输入长度为2-20位字符', 'tooShort'=>'{attribute}请输入长度为2-20位字符'],
            [['mobile'],'match','pattern'=>'/^[1][3456789][0-9]{9}$/','message' => '请输入正确的手机号'],
            [['username'],'match','pattern'=>'/^[0-9_a-zA-Z]{3,20}/','message' => '用户名只能由数字字母下划线组成'],
            ['repassword', 'compare', 'compareAttribute'=>'password','message' => '两次输入密码不一致'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => '用户id',
            'username' => '登录账号',
            'password' => '密码',
            'repassword' => '确认密码',
            'true_name' => '真实姓名',
            'mobile' => '手机号',
            'role_id' => '角色',
        ];
    }


    public function scenarios()
    {
        return [
            'default' => [
                'username',
                'password',
                'salt',
                'token',
                'mobile',
                'true_name',
                'repassword',
                'role_id'
            ],
            'create' => [
                'username',
                'password',
                'salt',
                'token',
                'status',
                'mobile',
                'true_name',
                'create_at',
                'update_at',
                'deleted_at',
            ],
            'update' => [
                'id',
                'username',
                'password',
                'salt',
                'token',
                'status',
                'mobile',
                'true_name',
                'create_at',
                'update_at',
                'deleted_at'
            ],
            'modify' => [
                'id',
                'password',
                'repassword',
            ],
            'modify_true' => [
                '!id',
                'password',
            ],
            'user_info' => [
                'true_name',
                'mobile',
                'avatar',
            ],
        ];
    }

    /**
     * 插入更新数据
     * @author hey_heyang(635870453@qq.com)
     */
    public  function saveUserInfo($scenario, $data, $user_id = 0){
        if (!in_array($scenario, ['create', 'update'])) {
            return false;
        }
        $t = static::getDb()->beginTransaction();
        try {
            if ($scenario == 'update') {
                $user_id = intval($user_id);
                if (!$user_id) {
                    return false;
                }
                $model           = static::findOne(['id' =>$user_id]);
                if(empty($model)) throw new Exception('不存在此用户');
                $model->scenario = 'update';
                if(!empty($data['username'])){
                    $have_username = $this->find()->where(['username' =>$data['username']])->andWhere(['<>','id', intval($user_id)])->asArray()->one();
                    if(!empty($have_username)) throw new Exception('用户名已存在！');
                }

            } else {
                $model           = new self();
                $model->scenario = 'create';
                unset($data['id']);
                
            }
            $model->setAttributes($data, false);
            if (!$model->save()) {
                $t->rollBack();
                return $model;
            }else{
                if($scenario == 'create'){
                    $groupaccess_model = new AuthGroupAccess();
                    $groupaccess_model::saveData(array('uid'=>intval($model->attributes['id']),'group_role_id'=>intval($data['role_id'])));
                }
            }
            $model->refresh();
            $t->commit();

            return $model;
        } catch (Exception $e) {
            $t->rollback();
            return $e;
        }
    }

    /**
     * 更新密码
     * @param  array $params
     * @param  array $user_id
     * @author hey_heyang(635870453@qq.com)
     * @return array|bool|\yii\db\ActiveRecord[]
     */
    public static function modifyPassword($params,$user_id)
    {
        $t = static::getDb()->beginTransaction();
        try {
            $model           = static::findOne(['id' =>intval($user_id)]);
            $model->scenario = 'modify_true';
            $info = $model->toArray();
            $params['password'] = sha1(md5($params['password'].$info['salt']));
            $model->setAttributes($params, false);
            if (!$model->save()) {
                $t->rollBack();
                return $model;
            }
            $model->refresh();
            $t->commit();
            return $model;
        } catch (Exception $e) {
            $t->rollback();
            return $e;
        }
    }


    /**
     * 更新用户信息
     * @param  array $params
     * @param  array $user_id
     * @author hey_heyang(635870453@qq.com)
     * @return array|bool|\yii\db\ActiveRecord[]
     */
    public static function updateUserInfo($params,$user_id)
    {
        $t = static::getDb()->beginTransaction();
        try {
            $model           = static::findOne(['id' =>intval($user_id)]);
            $model->scenario = 'user_info';
            $model->setAttributes($params, false);
            if (!$model->save()) {
                $t->rollBack();
                return $model;
            }
            $redis = Yii::$app->cache;
            $redis->hdel('user_info' ,'user_'.$user_id);
            $model->refresh();
            $t->commit();
            return $model;
        } catch (Exception $e) {
            $t->rollback();
            return $e;
        }
    }

    /**
     * @inheritdoc
     */
    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS]);
    }

    /**
     * @inheritdoc
     */
    public static function findDataByUsername($username)
    {
        return static::findOne(['username' => $username, 'status' => self::STATUS]);
    }

    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
    }

    /**
     * Finds user by password reset token
     *
     * @param string $token password reset token
     * @return static|null
     */
    public static function findByPasswordResetToken($token)
    {
        if (!static::isPasswordResetTokenValid($token)) {
            return null;
        }

        return static::findOne([
            'password_reset_token' => $token,
            'status' => self::STATUS_ACTIVE,
        ]);
    }

    /**
     * Finds out if password reset token is valid
     *
     * @param string $token password reset token
     * @return bool
     */
    public static function isPasswordResetTokenValid($token)
    {
        if (empty($token)) {
            return false;
        }

        $timestamp = (int) substr($token, strrpos($token, '_') + 1);
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
        return $timestamp + $expire >= time();
    }

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return bool if password provided is valid for current user
     */
    public function validatePassword($password)
    {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * Generates password hash from password and sets it to the model
     *
     * @param string $password
     */
    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomString();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken()
    {
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken()
    {
        $this->password_reset_token = null;
    }


    /**
     * 获取会员全部权限组
     * @param $user_id
     * @author hey_heyang(635870453@qq.com)
     */
    public  function  getAuthArray($user_id){
        $rules = (new Query())
            ->select('auth_group.rules')
            ->from('auth_group_access')
            ->innerJoin('auth_group','auth_group_access.group_role_id=auth_group.id')
            ->where(['and',['auth_group_access.uid' =>$user_id],['auth_group_access.deleted_at'=>null]])
            ->one();
        $auth_array = (new Query())
            ->select('name')
            ->from('auth_rule')
            ->where(['and','status=1',['in', 'id', explode(',',$rules['rules'])]])
            ->all();
        $auth_array = array_column($auth_array, 'name');
        if(!empty($auth_array)){
            array_map("strtolower", $auth_array);
        }
        return empty($auth_array)?array():$auth_array;
    }


    /**
     * 获取会员menu 权限
     * @param $user_id
     * @author hey_heyang(635870453@qq.com)
     */
    public  function  getMenuAuthArray($user_id){
        $rules = (new Query())
            ->select('auth_group.rules')
            ->from('auth_group_access')
            ->innerJoin('auth_group','auth_group_access.group_role_id=auth_group.id')
            ->where(['and',['auth_group_access.uid' =>$user_id],['auth_group_access.deleted_at'=>null]])
            ->one();
        $auth_array = (new Query())
            ->select('*')
            ->from('auth_rule')
            ->where(['and','status=1', 'ismenu=1', 'module="admin"',['in', 'id', explode(',',$rules['rules'])]])
            ->orderBy('sorts ASC,id ASC')
            ->all();

        //获取树型结构
        if(!empty($auth_array)){
            $tree = new tree();
            $auth_array = $tree->create($auth_array);
        }

        return empty($auth_array)?array():array_values($auth_array);

    }

    /**
     * 获取会员列表
     * @param $params
     * @author hey_heyang(635870453@qq.com)
     * @return array
     */
    public function getUserList($params){
        if(!empty($params['true_name']) && !empty($params['mobile'])){
            $condition = ['and','admin.status=1',['like','admin.true_name',$params['true_name']],['like','admin.mobile',$params['mobile']],['admin.deleted_at'=>null]];
        }elseif(!empty($params['true_name'])){
            $condition = ['and','admin.status=1',['like','admin.true_name',$params['true_name']],['admin.deleted_at'=>null]];
        }elseif(!empty($params['mobile'])){
            $condition = ['and','admin.status=1',['like','admin.mobile',$params['mobile']],['admin.deleted_at'=>null]];
        }else{
            $condition['admin.status']=1;
        }
        $list = (new Query())
            ->select('admin.id,admin.username,GROUP_CONCAT(auth_group.title) as role,admin.true_name,admin.mobile')
            ->from('admin')
            ->leftJoin('auth_group_access','auth_group_access.uid=admin.id')
            ->leftJoin('auth_group','auth_group_access.group_role_id=auth_group.id')
            ->where($condition)
            ->groupBy('id')
            ->all();
        return empty($list)?array():$list;

    }

    /**
     * 获取会员列表
     * @param $user_id
     * @author hey_heyang(635870453@qq.com)
     * @return array
     */
    public function getUserInfo($user_id){
        $redis = Yii::$app->cache;
        $user_info = $redis->hget('user_info' ,'user_'.$user_id);
        if(empty($user_info)){
            $user_info =static::findOne(['id' =>$user_id]);
            if($user_info){
                $user_info=$user_info->toArray();
                $redis->hset('user_info' ,'user_'.$user_id,json_encode($user_info));
                return $user_info;
            }else{
                return array();
            }
        }else{
            return json_decode($user_info,true);
        }

    }

    /**
     * 删除会员
     * @param $user_id
     * @author hey_heyang(635870453@qq.com)
     * @return array
     */
    public function deleteUser($user_id){
        $model = static::findOne(['id' =>$user_id]);
        if(empty($model)) return false;
        $params['status'] = 3;
        $params['deleted_at'] = time();
        $model->scenario = 'update';
        $model->setAttributes($params, false);
        if (!$model->save()) {
            return false;
        }else{
            $redis = Yii::$app->cache;
            $redis->hdel('user_info' ,'user_'.$user_id);
            return true;
        }
        }

    /**
     * 根据角色id获取用户信息
     * @param  int $id 更新id
     * @author hey_heyang(635870453@qq.com)
     * @return  array|bool|\yii\db\ActiveRecord[]
     */
    public  static function  getUserListByRole($id){
        $model = new self();
        $user_list_in = (new Query())
            ->select('admin.id,admin.username,admin.true_name')
            ->from('admin')
            ->innerJoin('auth_group_access','auth_group_access.uid=admin.id')
            ->where(['and','admin.status=1',['auth_group_access.group_role_id'=>intval($id)],['auth_group_access.deleted_at'=>null]])
            ->all();
        $user_list_all = $model->find()->select('id,username,true_name')->where(['status'=>1])->asArray()->all();
        $a=array_column($user_list_in,'id');
        $b=array_column($user_list_all,'id');
        $user_list_out  = array_diff($b,$a);
        foreach($user_list_all as $key=>$value){
            if(!in_array($value['id'],$user_list_out)){
                unset($user_list_all[$key]);
            }
        }
        return array('list_in'=>array_values($user_list_in),'list_out'=>array_values($user_list_all));

    }



    /**
     * 获取会员rule权限数组结构
     * @param $user_id
     * @author hey_heyang(635870453@qq.com)
     */
    public  function  getAuthRuleArray($user_id){
        $rules = (new Query())
            ->select('auth_group.rules')
            ->from('auth_group_access')
            ->innerJoin('auth_group','auth_group_access.group_role_id=auth_group.id')
            ->where(['and',['auth_group_access.uid' =>$user_id],['auth_group_access.deleted_at'=>null]])
            ->one();
        $auth_array = (new Query())
            ->select('*')
            ->from('auth_rule')
            ->where(['and','status=1', 'module="admin"',['in', 'id', explode(',',$rules['rules'])]])
            ->orderBy('sorts ASC,id ASC')
            ->all();
        return empty($auth_array)?array():array_values($auth_array);

    }



}
